package com.hakim.wfb.admin.service.impl;

import com.hakim.wfb.admin.enums.ErrorCodeEnum;
import com.hakim.wfb.admin.service.api.SystemAuthService;
import com.hakim.wfb.bean.Menu;
import com.hakim.wfb.bean.Role;
import com.hakim.wfb.bean.Admin;
import com.hakim.wfb.bean.AdminRole;
import com.hakim.wfb.admin.filter.*;
import com.hakim.wfb.admin.params.admin.*;
import com.hakim.wfb.admin.result.admin.*;
import com.hakim.wfb.dao.*;
import com.hkfs.fundamental.api.data.ListResultEx;
import com.hkfs.fundamental.api.data.ObjectResultEx;
import com.hkfs.fundamental.api.data.ResultEx;
import com.hkfs.fundamental.common.utils.StrUtils;
import com.hkfs.fundamental.validate.annotaion.ValidateFilters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 *
 */
@Service("systemAuthService")
public class SystemAuthServiceImpl implements SystemAuthService {

    private final Logger logger = LoggerFactory.getLogger(SystemAuthServiceImpl.class);

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private MenuRoleDao roleMenuDao;

    @Autowired
    private MenuDao menuDao;

    @Autowired
    private AdminDao adminDao;

    @Autowired
    private AdminRoleDao adminRoleDao;

    //region role

    /**
     * 查询角色列表
     *
     * @param param
     * @return
     */
    @Override
    public ListResultEx<RoleFullView> queryRoleList(QueryRoleParam param) {
        ListResultEx<RoleFullView> result = new ListResultEx<RoleFullView>();
        Role queryParam = new Role();
        queryParam.setRoleName(param.getRoleName());
        queryParam.setRequestCount(param.getRequestCount());
        queryParam.setRequestOffset(param.getRequestOffset());
        int totalCount = roleDao.count(queryParam);
        List<RoleFullView> list = new ArrayList<>();
        if (totalCount > 0) {

            list = roleDao.query(queryParam).stream().map(a -> {
                RoleFullView roleFullView = new RoleFullView();
                BeanUtils.copyProperties(a, roleFullView);
                return roleFullView;
            }).collect(Collectors.toList());
        }
        result.setTotalCount(totalCount);
        result.setDataList(list);
        return result.makeSuccessResult();
    }

    /**
     * 新增角色
     *
     * @param param
     * @return
     */
    @Override
    @Transactional
    @ValidateFilters(filterClasses = {AddRoleFilter.class})
    public ObjectResultEx<RoleView> addRole(AddRoleParam param) {
        Role addParam = new Role();
        addParam.setRoleName(param.getRoleName());
        addParam.setOptlock(param.getOptlock() == null ? 0 : param.getOptlock());
        addParam.setCreatedTime(new Date());
        addParam.setUpdatedTime(new Date());
        roleDao.add(addParam);
        //添加角色菜单
        if (param.getMenuIds() != null && param.getMenuIds().length > 0) {
            Map<String, Object> addMenuParam = new HashMap<String, Object>();
            addMenuParam.put("roleId", addParam.getId());
            addMenuParam.put("roleMenus", param.getMenuIds());
            roleMenuDao.addRoleMenu(addMenuParam);
        }

        QueryMenuParam queryMenuParam = new QueryMenuParam();
        queryMenuParam.setMenuIds(Arrays.asList(param.getMenuIds()));
        List<QueryMenuView> queryMenuViewList = menuDao.queryMenuList(queryMenuParam);

        ObjectResultEx<RoleView> result = new ObjectResultEx<RoleView>();
        RoleView retView = new RoleView();
        retView.setId(addParam.getId());
        retView.setRoleName(addParam.getRoleName());
        retView.setMenus(queryMenuViewList);
//        retView.setPowers(param.getPowers());
        result.setDataObject(retView);
        return result.makeSuccessResult();
    }

    @Override
    public ObjectResultEx<RoleView> getRole(GetRoleParam param) {
        ObjectResultEx<RoleView> result = new ObjectResultEx<RoleView>();
        //获取权限主体
        Role role = roleDao.getById(param.getId());
        if (role == null) {
            return result.makeFailedResult();
        }
        RoleView retView = new RoleView();
        retView.setId(role.getId());
        retView.setRoleName(role.getRoleName());
        retView.setOptlock(role.getOptlock());
        //获取角色的菜单及权限
        List<Long> menuIds = roleMenuDao.getMenuIdsByRoleId(role.getId());
        if (menuIds != null && menuIds.size() > 0) {
            QueryMenuParam queryMenuParam = new QueryMenuParam();
            queryMenuParam.setMenuIds(menuIds);
            List<QueryMenuView> queryMenuViewList = menuDao.queryMenuList(queryMenuParam);
            retView.setMenus(queryMenuViewList);
        }
        result.setDataObject(retView);
        return result.makeSuccessResult();
    }

    /**
     * 修改角色
     *
     * @param param
     * @return
     */
    @Override
    @Transactional
    @ValidateFilters(filterClasses = {ModifyRoleFilter.class})
    public ResultEx modifyRole(ModifyRoleParam param) {
        ResultEx result = new ResultEx();
        Role modParam = new Role();
        modParam.setId(param.getId());
        modParam.setRoleName(param.getRoleName());
        modParam.setUpdatedTime(new Date());
        int count = roleDao.update(modParam);
        if (count == 0) {
            result.makeResult(ErrorCodeEnum.ROLE_UPDATE_FAILED.getCode(), ErrorCodeEnum.ROLE_UPDATE_FAILED.getMessage());
            return result;
        }
        //修改角色菜单
        if (param.getMenuIds() != null) {
            Map<String, Object> modifyRoleMenuParam = new HashMap<String, Object>();
            modifyRoleMenuParam.put("roleId", param.getId());
            modifyRoleMenuParam.put("roleMenus", param.getMenuIds());
            roleMenuDao.deleteRoleMenu(modifyRoleMenuParam);
            roleMenuDao.addRoleMenu(modifyRoleMenuParam);
        } else {
            roleMenuDao.deleteMenuByRoleId(param.getId());
        }
        //修改角色权限
//        if(param.getPowers() != null && param.getPowers().length > 0){
//            Map<String, Object> modifyPowerParam = new HashMap<String, Object>();
//            modifyPowerParam.put("roleId", param.getId());
//            modifyPowerParam.put("rolePowers", param.getPowers());
//            rolePowerDao.deleteRolePower(modifyPowerParam);
////            rolePowerDao.addRolePower(modifyPowerParam);
//        }else{
//            rolePowerDao.deletePowerByRoleId(param.getId());
//        }
        return result.makeSuccessResult();
    }

    /**
     * 删除角色
     *
     * @param param
     * @return
     */
    @Transactional
    @Override
    @ValidateFilters(filterClasses = {DeleteRoleFilter.class})
    public ResultEx deleteRole(DeleteRoleParam param) {
        ResultEx result = new ResultEx();
        //删除菜单关联数据
        roleMenuDao.deleteMenuByRoleId(param.getRoleId());
        //删除权限关联数据
//        rolePowerDao.deletePowerByRoleId(param.getRoleId());
        int c = roleDao.delete(param.getRoleId());
        if (c == 0 || c > 1) {
            return result.makeFailedResult();
        }
        return result.makeSuccessResult();
    }
    //endregion

    //region user

    /**
     * 查询用户列表
     *
     * @param param
     * @return
     */
    @Override
    public ListResultEx<QueryAdminView> queryUserList(QueryAdminParam param) {

        ListResultEx<QueryAdminView> result = new ListResultEx<QueryAdminView>();
        int totalCount = adminDao.queryUserCount(param);
        List<QueryAdminView> list = new ArrayList<>();
        if (totalCount > 0) {

            list = adminDao.queryUserList(param);
        }
        result.setTotalCount(totalCount);
        result.setDataList(list);

        return result.makeSuccessResult();
    }

    @Override
    public ObjectResultEx<AdminRolesResultView> queryUserRoles(GetAdminParam param) {
        ObjectResultEx<AdminRolesResultView> result = new ObjectResultEx<AdminRolesResultView>();
        AdminRolesResultView view = new AdminRolesResultView();
        //查询包含角色信息的用户信息
        Admin user = adminDao.getById(param.getId());

        List<String> roles = adminRoleDao.getRoleIdsByUserId(param.getId());
        Long[] roleIds = new Long[roles.size()];
        int i = 0;
        for (String s : roles) {
            roleIds[i++] = Long.parseLong(s);
        }
        BeanUtils.copyProperties(user, view);
//        view.setId(user.getId());
        view.setRoleIds(roleIds);

        result.setDataObject(view);
        return result.makeSuccessResult();
    }

    /**
     * 添加用户
     *
     * @param param
     * @return
     */
    @Transactional
    @ValidateFilters(filterClasses = {AddAdminFilter.class})
    public ObjectResultEx<AdminFullView> addUser(AddAdminParam param) {
        Admin admin = new Admin();
        admin.setUserName(param.getUserName());
        admin.setCreatedtime(new Date());
        admin.setEmail(param.getEmail());
        admin.setPassword(StrUtils.getMd5(param.getPassword()));
        admin.setRealName(param.getRealName());
        adminDao.add(admin);

        //增加用户角色信息
        if (param.getRoleIds() != null && param.getRoleIds().length > 0) {
            Map<String, Object> modifyUserRoleParam = new HashMap<String, Object>();
            modifyUserRoleParam.put("userId", admin.getId());
            modifyUserRoleParam.put("roleIds", param.getRoleIds());
            adminRoleDao.addUserRole(modifyUserRoleParam);
        }

        ObjectResultEx<AdminFullView> result = new ObjectResultEx<AdminFullView>();
        AdminFullView adminFullView = new AdminFullView();
        BeanUtils.copyProperties(admin, adminFullView);
        result.setDataObject(adminFullView);
        return result.makeSuccessResult();
    }

    public ObjectResultEx<AdminFullView> getUser(GetAdminParam param) {
        Admin user = adminDao.getById(param.getId());
        ObjectResultEx<AdminFullView> result = new ObjectResultEx<>();
        AdminFullView userFullView = new AdminFullView();
        BeanUtils.copyProperties(user, userFullView);
        AdminRole userRole = new AdminRole();
        userRole.setUserId(param.getId());
        List<AdminRole> userRoleList = adminRoleDao.query(userRole);
        List<String> roleIds = new ArrayList<>();
        for (int i = 0; i < userRoleList.size(); i++) {
            String roleId = String.valueOf(userRoleList.get(i).getRoleId());
            roleIds.add(roleId);
        }
        userFullView.setRoleIds(roleIds);
        result.setDataObject(userFullView);
        return result.makeSuccessResult();
    }

    /**
     * 修改用户信息
     *
     * @param param
     * @return
     */
    @Override
    @Transactional
    @ValidateFilters(filterClasses = {ModifyAdminFilter.class})
    public ResultEx modifyUser(ModifyAdminParam param) {
        Admin user = new Admin();
        user.setId(param.getId());
        if (StrUtils.notEmpty(param.getUserName())) {
            user.setUserName(param.getUserName());
        }
        if (param.getStatus() != null) {
            user.setStatus(param.getStatus());
        }
        if (StrUtils.notEmpty(param.getEmail())) {
            user.setEmail(param.getEmail());
        }
        if (StrUtils.notEmpty(param.getPassword())) {
            user.setPassword(StrUtils.getMd5(param.getPassword()));
        }
//        if(param.getPositionId() != null){
//            user.setPositionId(param.getPositionId());
//        }
//        if(param.getRoleId() != null){//
//            user.setRoleId(param.getRoleId());
//        }
        //保存角色信息
//        Long[] roleIds = param.getRoleIds();
//        for(Long roleId:roleIds){
//            AdminRole ur = new AdminRole();
//            ur.setUserId(user.getId());
//            ur.setRoleId(roleId);
//            userRolesDao.add(ur);
//        }

        //修改角色菜单
        if (param.getRoleIds() != null && param.getRoleIds().length > 0) {
            Map<String, Object> modifyUserRoleParam = new HashMap<String, Object>();
            modifyUserRoleParam.put("userId", user.getId());
            modifyUserRoleParam.put("roleIds", param.getRoleIds());
            adminRoleDao.deleteUserRole(modifyUserRoleParam);
            adminRoleDao.addUserRole(modifyUserRoleParam);
        } else {
            //清空用户权限
            adminRoleDao.deleteRoleByUserId(user.getId());
        }

        if (StrUtils.notEmpty(param.getRealName())) {
            user.setRealName(param.getRealName());
        }
        if (param.getOptlock() != null) {
            user.setOptlock(param.getOptlock());
        }
        user.setUpdatedtime(new Date());
        ResultEx result = new ResultEx();
        int count = adminDao.update(user);
        if (count == 0) {
            result.makeResult(ErrorCodeEnum.USER_UPDATE_FAILED.getCode(), ErrorCodeEnum.USER_UPDATE_FAILED.getMessage());
            return result;
        }
        return result.makeSuccessResult();
    }
    //endregion

    //region menu

    /**
     * 查询菜单列表
     *
     * @param param
     * @return
     */
    @Override
    public ListResultEx<QueryMenuView> queryMenuList(QueryMenuParam param) {
        int totalCount = menuDao.queryMenuCount(param);
        ListResultEx<QueryMenuView> result = new ListResultEx<QueryMenuView>();
        List<QueryMenuView> list = new ArrayList<>();
        if (totalCount > 0) {
            list = menuDao.queryMenuList(param);
        }
        result.setTotalCount(totalCount);
        result.setDataList(list);

        return result.makeSuccessResult();
    }

    /**
     * 添加菜单
     *
     * @param param
     * @return
     */
    @Override
    @ValidateFilters(filterClasses = {AddMenuFilter.class})
    public ObjectResultEx<MenuFullView> addMenu(AddMenuParam param) {
        Menu menu = new Menu();
        menu.setMenuName(param.getMenuName());
        if (param.getParentId() != null) {
            menu.setParentId(param.getParentId());
        }
        if (StrUtils.notEmpty(param.getMenuPath())) {
            menu.setMenuPath(param.getMenuPath());
        }
        if (param.getOrderNum() != null) {
            menu.setOrderNum(param.getOrderNum());
        }
        menu.setCreatedTime(new Date());
        menu.setUpdatedTime(new Date());
        menuDao.add(menu);
        ObjectResultEx<MenuFullView> result = new ObjectResultEx<MenuFullView>();
        MenuFullView menuFullView = new MenuFullView();
        BeanUtils.copyProperties(menu, menuFullView);
        result.setDataObject(menuFullView);
        return result.makeSuccessResult();
    }

    @Override
    public ObjectResultEx<MenuFullView> getMenu(GetMenuParam param) {
        Menu getResult = menuDao.getById(param.getId());
        ObjectResultEx<MenuFullView> result = new ObjectResultEx<MenuFullView>();
        MenuFullView menuFullView = new MenuFullView();
        BeanUtils.copyProperties(getResult, menuFullView);
        result.setDataObject(menuFullView);
        return result.makeSuccessResult();
    }

    /**
     * 修改菜单
     *
     * @param param
     * @return
     */
    @Override
    @ValidateFilters(filterClasses = {ModifyMenuFilter.class})
    public ResultEx modifyMenu(ModifyMenuParam param) {
        Menu menu = new Menu();
        menu.setMenuName(param.getMenuName());
        menu.setId(param.getId());
        if (param.getParentId() != null) {
            menu.setParentId(param.getParentId());
        }
        if (StrUtils.notEmpty(param.getMenuPath())) {
            menu.setMenuPath(param.getMenuPath());
        }
        if (param.getOrderNum() != null) {
            menu.setOrderNum(param.getOrderNum());
        }
        menu.setUpdatedTime(new Date());
        int c = menuDao.update(menu);
        ResultEx result = new ResultEx();
        if (c == 0) {
            return result.makeFailedResult();
        }
        return result.makeSuccessResult();
    }

    /**
     * 删除菜单
     *
     * @param param
     * @return
     */
    @Transactional
    @Override
    @ValidateFilters(filterClasses = {DeleteMenuFilter.class})
    public ResultEx deleteMenu(DeleteMenuParam param) {
        roleMenuDao.deleteMenuByMenuId(param.getId());
        int c = menuDao.delete(param.getId());
        if (c == 0 || c > 1) {
            return new ResultEx().makeFailedResult();
        }
        return new ResultEx().makeSuccessResult();
    }

    @Override
    public ListResultEx<AdminMenuResultView> getUserMenu(GetAdminMenuParam param) {

        ListResultEx<AdminMenuResultView> result = new ListResultEx<>();
//        List<Menu> menuList1 = adminDao.getMenuByUserId(param.getSessionIdentity().getUserId());
        List<Menu> menuList = adminDao.getMenuByUserId2(param.getSessionIdentity().getUserId());
        if (menuList.size() == 0) {
            result.makeFailedResult("没有菜单记录");
        }
        List<AdminMenuResultView> adminMenuList = new ArrayList<>();
        for (int i = 0; i < menuList.size(); i++) {
            Menu menu = menuList.get(i);
            //顶级菜单
            if (menu.getParentId() == null || menu.getParentId() == 0) {
                AdminMenuResultView adminMenuView = new AdminMenuResultView();
                adminMenuView.setId(menu.getId());
                adminMenuView.setMenuName(menu.getMenuName());
                adminMenuView.setMenuPath(menu.getMenuPath());
                adminMenuView.setOrderNum(menu.getOrderNum());
                List<AdminMenuResultView> childMenuList = new ArrayList<>();
                adminMenuView.setChildMenus(childMenuList);
                adminMenuList.add(adminMenuView);
            } else {
                AdminMenuResultView adminMenuView = null;
                List<AdminMenuResultView> childMenuList = null;
                for (int j = 0; j < adminMenuList.size(); j++) {
                    if (menu.getParentId() == adminMenuList.get(j).getId()) {
                        adminMenuView = adminMenuList.get(j);
                        break;
                    }
                }
                if (adminMenuView != null) {
                    childMenuList = adminMenuView.getChildMenus();
                    AdminMenuResultView child = new AdminMenuResultView();
                    child.setId(menu.getId());
                    child.setMenuName(menu.getMenuName());
                    child.setMenuPath(menu.getMenuPath());
                    child.setOrderNum(menu.getOrderNum());
                    childMenuList.add(child);
                }
            }
        }
        result.setDataList(adminMenuList);
        return result.makeSuccessResult();
    }
    //endregion
}
